package top.lixunda.books3.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import top.lixunda.books3.dao.UserMapper;
import top.lixunda.books3.dao.UserBindMapper;
import top.lixunda.books3.entity.*;
import top.lixunda.books3.service.UserBindService;
import top.lixunda.books3.service.UserInfoService;
import top.lixunda.books3.service.UserService;
import top.lixunda.books3.util.Log;
import top.lixunda.books3.util.StringUtils;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private StringUtils stringUtils;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserBindMapper userbindMapper;
    @Autowired
    private HttpSession session;

    @Autowired
    private UserBindService userBindService;
    @Autowired
    private UserInfoService userInfoService;


    @Override
    public boolean judgeAllFormat(String username, String password, String verify) {
        return judgeUserNameFormat(username) && judgePasswordFormat(password) && judgeLoginVerifyFormat(verify);
    }

    /**
     * 登陆验证，主要负责系统账号登陆、手机号码登陆、邮箱账号登陆
     */
    @Override
    public int tempLogin(String username, String password) {
        User user = null;
        UserBind userbind = null;
        if(username.indexOf('@') > -1){
            //肯定是邮箱
            userbind = selectUserBindByKey(username, TYPE_EMAIL);
        }else if(username.length() >= 7 && username.startsWith("s") && Pattern.matches("^\\d+$", username.substring(1))){
            //肯定是系统账号
            long key;
            try{
                key = Long.parseLong(username.substring(1));
            }catch (Exception e){
                return CODE_ERROR_PARAMS;
            }
            user = selectUserByKey(key);
        }else if(username.length() == 11 && Pattern.matches("^\\d+$", username)){
            userbind = selectUserBindByKey(username, TYPE_PHONE);
        }else{
            return CODE_ERROR_PARAMS;
        }

        if(user == null && userbind == null){
            return CODE_NO_USER;
        }else if(user == null){
            user = selectUserByKey(userbind.getSystemid());
        }

        if(!user.getPassword().equals(password)){
            return CODE_ERROR_PASS;
        }
        //更新登录时间
        user.setLast(new Date().getTime());
        userMapper.updateByPrimaryKey(user);
        // 保存用户到session
        session.setAttribute("user", user);
        session.setAttribute("userBind", userbind);
        return CODE_SUCCESS;
    }

    @Override
    public boolean keyLogin(String loginKey) {
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();
        criteria.andLoginkeyEqualTo(loginKey);
        criteria.andLastGreaterThanOrEqualTo(new Date().getTime() - 30L*24*60*60*1000);
        List<User> list = userMapper.selectByExample(example);
        if(list.size() != 0){
            // 保存用户到session
            User user = list.get(0);
            user.setLast(new Date().getTime());
            userMapper.updateByPrimaryKey(user);
            user.setPassword("");
            session.setAttribute("user", user);
            Log.d("--------------> 通过了 key 登录了用户 "+user.getNickname());
            return true;
        }
        return false;
    }

    @Override
    public boolean doublePhoneUser(String phone) {
        return selectUserBindByKey(phone, TYPE_PHONE) != null;
    }

    @Override
    @Transactional
    public User register(String nickname, String phone, String password) {
        //1. 插入User
        User user = insertNewSystemUser(nickname, password);
        if(user == null){
            Log.d("新建系统user失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return null;
        }
        //2. 插入UserBind
        UserBind userbind = userBindService.bindToSystemUser(user.getSystemid(), phone, TYPE_PHONE);
        if(userbind == null){
            Log.d("手机用户："+phone+" 绑定系统："+user.getSystemid()+" 失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return null;
        }
        //3. 插入手机号码信息
        UserInfo userInfo = new UserInfo();
        userInfo.setSystemid(user.getSystemid());
        userInfo.setPhone(phone);
        userInfoService.insertUserInfo(userInfo);
        return user;
    }

    @Override
    public String createLoginKey(User user) {
        //1. 产生一个唯一的loginKey
        String key = createOnlyLoginKey();
        //2. 添加到user表中
        user.setLoginkey(key);
        user.setLast(new Date().getTime());
        userMapper.updateByPrimaryKey(user);
        return key;
    }

    @Override
    public User insertNewSystemUser(String nickname, String password) {
        User user = new User();
        user.setNickname(nickname);
        user.setPassword(password);
        user.setPermission(6);
        user.setTime(new Date().getTime());
        user.setLoginkey("");
        user.setLast(0L);
        if(userMapper.insert(user) == 0){
            return null;
        }
        return user;
    }

    private User selectUserByKey(long key){
        return userMapper.selectByPrimaryKey(key);
    }

    private UserBind selectUserBindByKey(String id, String type){
        UserBindKey userbindKey = new UserBindKey();
        userbindKey.setId(id);
        userbindKey.setUsertype(type);
        return userbindMapper.selectByPrimaryKey(userbindKey);
    }

    @Override
    public boolean judgeUserNameFormat(String username){
        return true;
    }

    @Override
    public boolean judgePasswordFormat(String password){
        return !(password == null || password.length() < 8 || password.length() > 20 ||
                Pattern.matches("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]$",password));
    }

    @Override
    public boolean judgeLoginVerifyFormat(String verify){
        return true;
    }

    @Override
    public boolean judgePhoneFormat(String phone) {
        return !(phone == null || phone.length() != 11 || !Pattern.matches("^1[34578][0-9]{9}$", phone));
    }

    @Override
    public boolean judgeStringFormat(String str) {
        return true;
    }

    private String createOnlyLoginKey(){
        while(true){
            String key = stringUtils.randomString(32);
            UserExample example = new UserExample();
            UserExample.Criteria criteria = example.createCriteria();
            criteria.andLoginkeyEqualTo(key);
            if(userMapper.selectByExample(example).size() == 0){
                return key;
            }
        }
    }

}
